<?php

namespace app\common\logic;

use app\common\model\AdminRoleAccessModel;
use app\common\model\AdminUserModel;
use app\common\validate\AdminUserValidate;
use plugins\upload\model\AttachmentModel;
use think\db\exception\DataNotFoundException;
use think\db\exception\DbException;
use think\db\exception\ModelNotFoundException;
use think\exception\ValidateException;
use think\facade\Event;
use think\facade\Log;
use tinywan\JWT;

class AdminUserLogic extends BaseLogic
{

    public function _initialize(): void
    {
        parent::_initialize();
    }

    public static function getList(array $condition = [], string $returnType = 'normal'): array
    {
        $list = (new AdminUserModel)->with(['dept'])->where(convertModelCondition($condition))->order('id', 'desc')->paginate(10);
        return $list->toArray();
    }


    /**
     * 管理员登录
     *
     * @param string $username    用户名
     * @param string $password    登录密码
     * @param string $captcha     验证码
     * @param string $captchaCode 验证码校验码
     *
     * @return array|string|void
     */
    public static function Login(string $username, string $password, string $captcha = '', string $captchaCode = '')
    {
        // 当不输入验证码，则不进行验证码校验
        $scene = empty($captcha) && empty($captchaCode) ? 'loginNotCaptcha' : 'login';
        try {
            validate(AdminUserValidate::class)
                ->scene($scene)
                ->check([
                            'username'    => $username,
                            'password'    => $password,
                            'captcha'     => $captcha,
                            'captchaCode' => $captchaCode
                        ]);
            $user = AdminUserModel::Login($username, $password);
            if (is_array($user)) {
                $buildToken           = [
                    'id'   => $user['id'],
                    'name' => $user['username']
                ];
                $token                = JWT::generateToken($buildToken);
                $user['accessToken']  = $token['access_token'];
                $user['refreshToken'] = $token['refresh_token'];
                $user['expires']      = (time() + intval($token['expires_in'])) * 1000;
                Event::trigger('AdminUserLoginSuccess', $user);
            }
            return $user;
        } catch (ValidateException $e) {
            Log::write($e);
            return $e->getError();
        }
    }

    /**
     * 刷新token
     *
     * @return array|string
     */
    public static function refreshToken(): array|string
    {
        $user = JWT::verify(2);
        if (empty($user['extend'])) {
            return '用户信息不存在';
        }
        $userExtend = $user['extend'];
        $Token      = JWT::generateToken($userExtend);
        return [
            'accessToken'  => $Token['access_token'],
            'refreshToken' => $Token['refresh_token'],
            'expires'      => (time() + intval($Token['expires_in'])) * 1000
        ];
    }


    /**
     * 根据ID获取某一用户信息
     *
     * @param int $id
     *
     * @return array
     */
    public static function getAdminUserById(int $id): array
    {
        try {
            return (new AdminUserModel)->find($id)->toArray();
        } catch (DataNotFoundException|ModelNotFoundException|DbException $e) {
            return [];
        }
    }

    /**
     * 获取某一用户所有角色ID
     *
     * @param int $user_id
     *
     * @return array
     */
    public static function getUserRoles(int $user_id): array
    {
        return (new AdminRoleAccessModel)->where('user_id', $user_id)->column('role_id');
    }

    /**
     * 更新用户信息
     */
    public static function updateUserInfo(array $data): bool|string
    {
        $user_id = $data['id'] ?? 0;
        unset($data['id']);
        $scene = $user_id ? 'update' : 'create';
        try {
            validate(AdminUserValidate::class)
                ->scene($scene)
                ->check($data);
            if (isset($data['password']) && strlen($data['password']) > 0) $data['password'] = md5(sha1($data['password']));
            if ($user_id) {
                $allowFields = ['username', 'nickname', 'password', 'mobile', 'email', 'department_id'];
                $result      = (new AdminUserModel)->update($data, ['id' => $user_id], $allowFields);
            } else {
                $result = (new AdminUserModel)->create($data);
            }
            if ($result) {
                return true;
            } else {
                return '保存失败';
            }
        } catch (ValidateException $e) {
            return $e->getMessage();
        }
    }

    /**
     * 更新用户指定字段
     *
     * @param array $data
     *
     * @return bool|string
     */
    public static function updateUserField(array $data): bool|string
    {
        $result      = (new AdminUserModel)->update($data);
        if ($result){
            return true;
        }else{
            return '保存失败';
        }
    }

    /**
     * 设置用户角色
     *
     * @param int $user_id
     * @param array $role_ids
     *
     * @return bool|string
     */
    public static function setUserRoles(int $user_id, array $role_ids) : bool|string
    {
        // 取用户已存在的所有角色ID
        $userRoleIds = (new AdminRoleAccessModel)->where('user_id', $user_id)->column('role_id');
        // 记录已经不在的角色ID随后删除
        $deleteRoleIds = array_diff($userRoleIds, $role_ids);
        // 取需要新增的角色ID
        $addRoleIds = array_diff($role_ids, $userRoleIds);
        try {
            if ($deleteRoleIds) {
                (new AdminRoleAccessModel)->where('user_id', $user_id)->whereIn('role_id', $deleteRoleIds)->delete();
            }
            if ($addRoleIds) {
                $addData = [];
                foreach ($addRoleIds as $role_id) {
                    $addData[] = [
                        'user_id' => $user_id,
                        'role_id' => $role_id
                    ];
                }
                (new AdminRoleAccessModel)->insertAll($addData);
            }
            return true;
        } catch (DbException $e) {
            return $e->getMessage();
        }
    }

    /**
     * 删除用户
     *
     * @param int $user_id
     *
     * @return bool|string
     */
    public static function deleteUser(int $user_id) : bool|string
    {
        // 取用户信息
        $userInfo = (new AdminUserModel)->findOrEmpty($user_id);
        if ($userInfo->isEmpty()) {
            return '用户不存在';
        }
        // 删除用户头像及头像图片文件
        if ($userInfo->avatar) {
            AttachmentModel::deleteAttachment($userInfo->avatar);
        }
        // 删除用户所属角色
        AdminRoleAccessModel::deleteUserRoles($user_id);
        // 删除用户信息
        $result = $userInfo->delete();
        if ($result) {
            Event::trigger('deleteAdminUserSuccess', ['user_id' => $user_id]);
            return true;
        } else {
            return '删除失败';
        }
    }
}